package player

import (
    "context"
    "errors"
    "fmt"
    "log"
    "sync"
    "time"

    "google.golang.org/grpc"
    pb "your_project/proto"
    "your_project/data"
)

// PlayerManager 玩家管理器
type PlayerManager struct {
    players      map[int64]*Player // 玩家ID -> 玩家对象
    playersMutex sync.RWMutex
    
    // gRPC客户端
    worldClient pb.WorldServiceClient
}

// Player 玩家对象
type Player struct {
    ID           int64
    AccountID    int64
    CharacterID  int64
    Name         string
    Level        int32
    Class        string
    Health       int32
    MaxHealth    int32
    Position     *pb.Position
    SceneID      int32
    ConnectionID string
    LastActive   time.Time
    
    // 临时数据
    IsOnline     bool
}

// GetInstance 获取玩家管理器实例
func GetInstance() *PlayerManager {
    return playerManagerInstance
}

var playerManagerInstance = &PlayerManager{
    players: make(map[int64]*Player),
}

// Init 初始化玩家管理器
func (pm *PlayerManager) Init(worldConn *grpc.ClientConn) {
    pm.worldClient = pb.NewWorldServiceClient(worldConn)
    log.Println("Player manager initialized")
}

// LoginPlayer 处理玩家登录
func (pm *PlayerManager) LoginPlayer(accountID, characterID int64, connID string) (*Player, error) {
    pm.playersMutex.Lock()
    defer pm.playersMutex.Unlock()
    
    // 检查玩家是否已登录
    if player, exists := pm.players[characterID]; exists {
        if player.IsOnline {
            return nil, errors.New("player already logged in")
        }
    }
    
    // 从数据库加载玩家数据
    playerData, err := data.LoadPlayerData(characterID)
    if err != nil {
        return nil, fmt.Errorf("failed to load player data: %v", err)
    }
    
    // 解析玩家数据
    player := &Player{
        ID:           characterID,
        AccountID:    accountID,
        CharacterID:  characterID,
        Name:         "PlayerName", // 从playerData解析
        Level:        1,            // 从playerData解析
        Class:        "Warrior",    // 从playerData解析
        Health:       100,          // 从playerData解析
        MaxHealth:    100,          // 从playerData解析
        Position:     &pb.Position{X: 0, Y: 0, Z: 0}, // 从playerData解析
        SceneID:      1,            // 从playerData解析
        ConnectionID: connID,
        LastActive:   time.Now(),
        IsOnline:     true,
    }
    
    // 保存玩家对象
    pm.players[characterID] = player
    
    // 通知世界服务器玩家登录
    _, err = pm.worldClient.PlayerLogin(context.Background(), &pb.PlayerLoginRequest{
        PlayerId:  characterID,
        Name:      player.Name,
        SceneId:   player.SceneID,
        Position:  player.Position,
    })
    
    return player, err
}

// LogoutPlayer 处理玩家登出
func (pm *PlayerManager) LogoutPlayer(playerID int64) error {
    pm.playersMutex.Lock()
    defer pm.playersMutex.Unlock()
    
    player, exists := pm.players[playerID]
    if !exists || !player.IsOnline {
        return errors.New("player not logged in")
    }
    
    // 更新玩家状态
    player.IsOnline = false
    player.ConnectionID = ""
    
    // 保存玩家数据
    err := pm.savePlayerData(playerID)
    if err != nil {
        log.Printf("Failed to save player data on logout: %v", err)
    }
    
    // 通知世界服务器玩家登出
    _, err = pm.worldClient.PlayerLogout(context.Background(), &pb.PlayerLogoutRequest{
        PlayerId: playerID,
        SceneId:  player.SceneID,
    })
    
    return err
}

// MovePlayer 处理玩家移动
func (pm *PlayerManager) MovePlayer(playerID int64, position *pb.Position) error {
    pm.playersMutex.RLock()
    defer pm.playersMutex.RUnlock()
    
    player, exists := pm.players[playerID]
    if !exists || !player.IsOnline {
        return errors.New("player not logged in")
    }
    
    // 更新玩家位置
    player.Position = position
    player.LastActive = time.Now()
    
    // 通知世界服务器玩家移动
    _, err := pm.worldClient.PlayerMove(context.Background(), &pb.PlayerMoveRequest{
        PlayerId: playerID,
        SceneId:  player.SceneID,
        Position: position,
    })
    
    return err
}

// savePlayerData 保存玩家数据
func (pm *PlayerManager) savePlayerData(playerID int64) error {
    pm.playersMutex.RLock()
    defer pm.playersMutex.RUnlock()
    
    player, exists := pm.players[playerID]
    if !exists {
        return errors.New("player not found")
    }
    
    // 序列化玩家数据
    // 这里应该使用Protobuf序列化玩家数据
    playerData := []byte(fmt.Sprintf(`{"id":%d,"name":"%s","level":%d}`, 
        player.ID, player.Name, player.Level))
    
    // 保存到数据库
    return data.SavePlayerData(playerID, playerData)
}

// GetPlayer 获取玩家对象
func (pm *PlayerManager) GetPlayer(playerID int64) (*Player, bool) {
    pm.playersMutex.RLock()
    defer pm.playersMutex.RUnlock()
    
    player, exists := pm.players[playerID]
    return player, exists
}

// GetOnlinePlayers 获取在线玩家列表
func (pm *PlayerManager) GetOnlinePlayers() []*Player {
    pm.playersMutex.RLock()
    defer pm.playersMutex.RUnlock()
    
    onlinePlayers := make([]*Player, 0, len(pm.players))
    for _, player := range pm.players {
        if player.IsOnline {
            onlinePlayers = append(onlinePlayers, player)
        }
    }
    
    return onlinePlayers
}    